/*
 * Copyright 2024 The JA-SIG Collaborative. All rights reserved. distributed with thi file and
 * available online at
 */
package com.lap.auth.domain.user;

import com.lap.auth.domain.shared.errors.UserError;
import com.lap.auth.domain.user.event.UserCreatedEvent;
import com.lap.auth.domain.user.event.UserEnabledEvent;
import com.lap.auth.domain.user.event.UserUpdateEvent;
import com.lap.auth.domain.user.valueobject.StatusType;
import com.lap.auth.domain.user.valueobject.UserType;
import com.lap.framework.ddd.AggregateRoot;
import com.lap.framework.exception.BizException;
import java.time.LocalDate;
import lombok.Getter;

/**
 * 系统管理员领域
 *
 * @author Shuisheng Lao(劳水生)
 * @version 0.0.1
 */
@Getter
public class User extends AggregateRoot {

  private final Integer id;
  private final String username;
  private final String fullName;
  private final String email;
  private final Integer orgId;
  private final String orgPath;
  private final Integer jobId;
  private final LocalDate termValidity;
  private final UserType type;
  private String remark;
  private String password;
  private StatusType status;
  private Long version;

  public User(
      Integer id,
      String username,
      String fullName,
      String email,
      LocalDate termValidity,
      String remark,
      Integer orgId,
      String orgPath,
      Integer jobId,
      Long version,
      UserType type,
      String password,
      StatusType status) {
    // 需要校验的，就校验
    this.id = id;
    this.username = username;
    this.fullName = fullName;
    this.email = email;
    this.termValidity = termValidity;
    this.remark = remark;
    this.orgId = orgId;
    this.orgPath = orgPath;
    this.jobId = jobId;
    this.password = password;
    this.status = status;
    this.version = version;
    this.type = type;
  }

  public void createEvent() {
    registerEvent(new UserCreatedEvent(this));
  }

  public void updateEvent() {
    registerEvent(new UserUpdateEvent(this));
  }

  /** 用户禁用 */
  public void disable(String remark, Long version) {
    validateBeforeStatus(StatusType.DISABLED);
    this.status = StatusType.DISABLED;
    this.remark = remark;
    this.version = version;

    registerEvent(new UserEnabledEvent(id, status));
  }

  /** 用户启用 */
  public void enable(String remark, Long version) {
    validateBeforeStatus(StatusType.ENABLED);
    this.status = StatusType.ENABLED;
    this.remark = remark;
    this.version = version;

    registerEvent(new UserEnabledEvent(id, status));
  }

  /**
   * 启用或者禁用校验
   *
   * @param status 状态枚举
   */
  private void validateBeforeStatus(StatusType status) {
    if (type.canNotModify()) {
      BizException.interrupt(UserError.USER_CHANGE_NOT_ALLOW);
    }
    if (this.status == status) {
      BizException.interrupt(UserError.USER_STATUS_FAIL);
    }
  }

  public void changePassword(String encodePassword) {
    this.password = encodePassword;
    registerEvent(new UserEnabledEvent(id, status));
  }

  public boolean isActive() {
    return StatusType.ENABLED == status;
  }

  public void assertUserActive() {
    if (!isActive()) {
      BizException.interrupt(UserError.LOGIN_FAIL);
    }
  }

  public boolean isNew() {
    return id == null;
  }
}
